(define (cons-stream x y)
    (cons x (delay y))
)

(define (stream-car s) (car s))
(define (stream-cdr s) (force (cdr s)))

(define (stream-ref s n)
    (if (= n 0)
        (stream-car s)
        (stream-ref (stream-cdr s) (- n 1))
    )
)
(define (stream-map proc s)
    (if (null? s)
        `()
        (cons-stream 
            (proc (stream-car s))
            (stream-map proc (stream-cdr s))
        )
    )
)

(define (stream-for-each proc s)
    (if (null? s)
        `done
        (begin
            (proc (stream-car s))
            (stream-for-each proc (stream-cdr s))
        )
    )
)

(define (stream-filter pred s)
    (cond 
        ((null? s) `())
        ((pred (stream-car s))
            (cons-stream 
                (stream-car s)
                (stream-filter pred (stream-cdr s))
            )
        )
        (else (stream-filter pred (stream-cdr s)))
    )
)

(define (display-stream s)
    (stream-for-each display-line s)
)
(define (display-line x)
    (newline)
    (display x)
)


(define (stream-enumerate-interval low height)
    (if (> low height)
        `()
        (cons-stream 
            low
            (stream-enumerate-interval (+ low 1) height)
        )
    )
)


(define sum 0)
(define (accum x)
    (set! sum (+ x sum))
    sum
)

(define seq (stream-map accum (stream-enumerate-interval 1 20)))
(define y (stream-filter even? seq))
(define z 
    (stream-filter 
        (lambda (x) 
            (= (remainder x 5 ) 0)
        )
        seq
    )
)

(stream-ref y 7)
(newline)
(display "sum=")
(display sum)

(display-stream z)
(newline)
(display "sum=")
(display sum)

(exit)